-- Copyright (c) 2010, Pavel Kovar
-- All rights reserved.
--
---------------------------------------------------------------------------------------
-- This file is a part of the Witch Navigator project

-- Universal Correlator top level
-- Implemented
--   * Building blocks interconnection
--   * Memory for correlator input registers (nco_phase and nco_phase controlled}
--   * Memory for nco_code and nco_phase state
--   * Memory for correlators output
--   * Memory for signal samples capture
--   * Auxiliary registers
--   * Address decoder for memory write
--   * Address decoder for memory read 


library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

---- Uncomment the following library declaration if instantiating
---- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;

entity cor_top is
GENERIC (
		-- TIC period definition in clk_in cycles
		tic_length : integer := 16000;
		
		-- PRN length in chips
		-- 10230 for L5, E5a, E5b
		-- 10230 L1, PRN bits are repeated ten times
		-- 10220 for Glonass L1 (1ms), PRN bits are repeated twenty times
		
		-- 8184 (4092*2) for E1b, E1c (4 ms) PRN tic evan generates each millisecond, sets automatically
		-- PRN code + BOC1,1
		prn_length1_6 : integer := 10230;
		prn_length7_12 : integer := 10230;
		prn_length13_18 : integer := 10230;
		prn_length19_24 : integer := 10230
		);

PORT(
		clk_in : IN std_logic;  -- 20MHz, from crystal oscillator.
		clk_ctr : IN std_logic; -- trn_clk, 100M/125M, output from PCIe bus.
        clkdsp : OUT std_logic; -- 120M, output from PLL which is generated from clk_in
		s1_in : IN std_logic_vector(7 downto 0);
		s2_in : IN std_logic_vector(7 downto 0);
		agc1 : OUT std_logic;
		agc2 : OUT std_logic;
		clk_adc : OUT std_logic;
		inmem_addr : IN std_logic_vector(19 downto 0);
		inmem_we : IN std_logic_vector(3 downto 0);
		inmem_data : IN std_logic_vector(31 downto 0);
		outmem_addr : IN std_logic_vector(19 downto 0);
		outmem_data : OUT std_logic_vector(31 downto 0);
		outmem_ce : IN std_logic;
		i2c_status : IN std_logic_vector(31 downto 0);
		i2c_control : OUT std_logic_vector(31 downto 0);
		tic_out : OUT std_logic;
		pcie_rst_n: IN std_logic;
		dma_wr_addr : OUT std_logic_vector(31 downto 0);
		dma_ctrl : OUT std_logic;
		led_1, led_2 : OUT std_logic;
		irq_enable : OUT std_logic--;
		-- test outputs
--		b_code_test : out std_logic_vector(31 downto 0);
--		b_phase_test : out std_logic_vector(31 downto 0);
--		sr_in_test : out std_logic_vector(7 downto 0);
--		si_in_test : out std_logic_vector(7 downto 0);
--		cor_space_test : out std_logic_vector(2 downto 0);
--		phase_test : out std_logic_vector(2 downto 0);
--		nco_code_out_test : out std_logic_vector(31 downto 0);
--		nco_phase_out_test : out std_logic_vector(31 downto 0);
--		acc_e_out_test : out std_logic_vector(31 downto 0);
--		acc_l_out_test : out std_logic_vector(31 downto 0);
--		prn_tic_e_test : out std_logic;
--		prn_tic_l_test : out std_logic
		-- end of test outputs		
);
end cor_top;

architecture Behavioral of cor_top is

signal clk_dsp: std_logic;
signal tic: std_logic;
signal tic_page, tic_page_early: std_logic;
signal phase, phase_early: std_logic_vector(2 downto 0);
signal sr1_out, sr2_out, si1_out, si2_out: std_logic_vector(7 downto 0); 
signal cor_space : std_logic_vector(2 downto 0);

signal acq_mem_we: std_logic_vector(0 downto 0);
signal acq_mem_in: std_logic_vector(15 downto 0);
signal acq_mem_addr_in: std_logic_vector(14 downto 0);
signal acq_mem_out: std_logic_vector(31 downto 0);
signal acq_mem_addr_out: std_logic_vector(13 downto 0);

signal cor_mem_addr, nco_mem_addr: std_logic_vector(3 downto 0);

signal nco_imem_we1: std_logic_vector(3 downto 0);
signal nco_imem_we2: std_logic_vector(3 downto 0);
signal nco_imem_addr: std_logic_vector(5 downto 0);
signal nco_imem_out1: std_logic_vector(127 downto 0);
signal nco_imem_out2: std_logic_vector(127 downto 0);

signal nco_omem_we: std_logic_vector(0 downto 0);
signal nco_omem_in: std_logic_vector(255 downto 0);
signal nco_omem_addr: std_logic_vector(6 downto 0);
signal nco_omem_out: std_logic_vector(31 downto 0);

signal cor_mem_in1, cor_mem_in2: std_logic_vector(127 downto 0);
signal cor_mem_out1, cor_mem_out2: std_logic_vector(31 downto 0); 
signal cor_mem_we1, cor_mem_we2: std_logic_vector(15 downto 0);
signal cor_mem_addr_out: std_logic_vector(5 downto 0);

signal outmem_addr_delay: std_logic_vector(19 downto 0); 

signal cor_space_in_reg: std_logic_vector(31 downto 0);
signal i2c_controlr: std_logic_vector(31 downto 0);

signal b_code1, b_code2, b_code3, b_code4: std_logic_vector(31 downto 0);
signal b_phase1, b_phase2, b_phase3, b_phase4: std_logic_vector(31 downto 0);

signal codem_1, codem_2, codem_3, codem_4: std_logic_vector(31 downto 0);
signal phasem_1, phasem_2, phasem_3, phasem_4: std_logic_vector(31 downto 0);

signal acc_e_out1, acc_e_out2, acc_e_out3, acc_e_out4 : std_logic_vector(31 downto 0);
signal acc_l_out1, acc_l_out2, acc_l_out3, acc_l_out4 : std_logic_vector(31 downto 0);

signal prn_tic_e1, prn_tic_e2, prn_tic_e3, prn_tic_e4: std_logic;
signal prn_tic_l1, prn_tic_l2, prn_tic_l3, prn_tic_l4: std_logic;

signal prn_mem_we1, prn_mem_we2, prn_mem_we3, prn_mem_we4: std_logic_vector(3 downto 0);

signal dma_wr_addr_reg: std_logic_vector(31 downto 0);
signal cor_ctrl, tic_no: std_logic_vector(31 downto 0);

	COMPONENT cor6
	GENERIC (
	  prn_length : integer
	  );
	PORT(
		sr_in : IN std_logic_vector(7 downto 0);
		si_in : IN std_logic_vector(7 downto 0);
		clk_dsp : IN std_logic;
		b_code : IN std_logic_vector(31 downto 0);
		b_phase : IN std_logic_vector(31 downto 0);
		cor_space : IN std_logic_vector(2 downto 0);
		phase : IN std_logic_vector(2 downto 0);
		clk_ctr : IN std_logic;
		prn_mem_we : IN std_logic_vector(3 downto 0);
		prn_mem_addr : IN std_logic_vector(11 downto 0);
		prn_mem_in : IN std_logic_vector(31 downto 0);          
		nco_code_out : OUT std_logic_vector(31 downto 0);
		nco_phase_out : OUT std_logic_vector(31 downto 0);
		acc_e_out : OUT std_logic_vector(31 downto 0);
		acc_l_out : OUT std_logic_vector(31 downto 0);
		prn_tic_e : OUT std_logic;
		prn_tic_l : OUT std_logic
		);
	END COMPONENT;

	COMPONENT cor_timing
	GENERIC (
	   tic_length : integer
		);
	PORT(
		clk_in : IN std_logic;
		s1_in : IN std_logic_vector(7 downto 0);
		s2_in : IN std_logic_vector(7 downto 0);
		acq_ctr : IN std_logic_vector(3 downto 0);          
		clk_adc : OUT std_logic;
		clk_dsp : OUT std_logic;
		tic : OUT std_logic;
		dma_ctrl : OUT std_logic;
		phase : OUT std_logic_vector(2 downto 0);
		tic_page : OUT std_logic;
		phase_early : OUT std_logic_vector(2 downto 0);
		tic_page_early : OUT std_logic;
		sr1_out : OUT std_logic_vector(7 downto 0);
		si1_out : OUT std_logic_vector(7 downto 0);
		sr2_out : OUT std_logic_vector(7 downto 0);
		si2_out : OUT std_logic_vector(7 downto 0);
		agc1 : OUT std_logic;
		agc2 : OUT std_logic;
		acq_mem_addr : OUT std_logic_vector(13 downto 0);
		acq_mem_we : OUT std_logic;
		acq_mem_data : OUT std_logic_vector(15 downto 0);
		tic_no_counter : OUT std_logic_vector(15 downto 0)
		);
	END COMPONENT;


component cor_outmem
	port (
	clka: IN std_logic;
	wea: IN std_logic_VECTOR(15 downto 0);
	addra: IN std_logic_VECTOR(3 downto 0);
	dina: IN std_logic_VECTOR(127 downto 0);
	clkb: IN std_logic;
	enb: IN std_logic;
	addrb: IN std_logic_VECTOR(5 downto 0);
	doutb: OUT std_logic_VECTOR(31 downto 0));
end component;

component acq_outmem
	port (
	clka: IN std_logic;
	wea: IN std_logic_VECTOR(0 downto 0);
	addra: IN std_logic_VECTOR(14 downto 0);
	dina: IN std_logic_VECTOR(15 downto 0);
	clkb: IN std_logic;
	enb: IN std_logic;
	addrb: IN std_logic_VECTOR(13 downto 0);
	doutb: OUT std_logic_VECTOR(31 downto 0));
end component;

component nco_outmem
	port (
	clka: IN std_logic;
	wea: IN std_logic_VECTOR(0 downto 0);
	addra: IN std_logic_VECTOR(3 downto 0);
	dina: IN std_logic_VECTOR(255 downto 0);
	clkb: IN std_logic;
	enb: IN std_logic;
	addrb: IN std_logic_VECTOR(6 downto 0);
	doutb: OUT std_logic_VECTOR(31 downto 0));
end component;


component nco_inmem
	port (
	clka: IN std_logic;
	wea: IN std_logic_VECTOR(3 downto 0);
	addra: IN std_logic_VECTOR(5 downto 0);
	dina: IN std_logic_VECTOR(31 downto 0);
	clkb: IN std_logic;
	addrb: IN std_logic_VECTOR(3 downto 0);
	doutb: OUT std_logic_VECTOR(127 downto 0));
end component;

begin

tic_out <= tic;
clkdsp <= clk_dsp;

-- write to registers
process(clk_ctr,pcie_rst_n)
begin
	if pcie_rst_n='0' then
		cor_ctrl <= "00000000000000000000000000000000"; 
	elsif clk_ctr'event and clk_ctr='1' then
		-- 010 xxxx xxxx 0000 - cor_ctrl
		if inmem_we(0)='1' and  inmem_addr(14 downto 12) = "010" and inmem_addr(3 downto 0)="0000" then 
			cor_ctrl(7 downto 0) <= inmem_data(7 downto 0);
		end if;
		if inmem_we(1)='1' and  inmem_addr(14 downto 12) = "010" and inmem_addr(3 downto 0)="0000" then 
			cor_ctrl(15 downto 8) <= inmem_data(15 downto 8);
		end if;
		if inmem_we(2)='1' and  inmem_addr(14 downto 12) = "010" and inmem_addr(3 downto 0)="0000" then 
			cor_ctrl(23 downto 16) <= inmem_data(23 downto 16);
		end if;
		if inmem_we(3)='1' and  inmem_addr(14 downto 12) = "010" and inmem_addr(3 downto 0)="0000" then 
			cor_ctrl(31 downto 24) <= inmem_data(31 downto 24);
		end if;
		-- 010 xxxx xxxx 0001 - dma_wr_addr_reg(31 downto 0)
		if inmem_we(0)='1' and  inmem_addr(14 downto 12) = "010" and inmem_addr(3 downto 0)="0001" then 
			dma_wr_addr_reg(7 downto 0) <= inmem_data(7 downto 0);
		end if;
		if inmem_we(1)='1' and  inmem_addr(14 downto 12) = "010" and inmem_addr(3 downto 0)="0001" then 
			dma_wr_addr_reg(15 downto 8) <= inmem_data(15 downto 8);
		end if;
		if inmem_we(2)='1' and  inmem_addr(14 downto 12) = "010" and inmem_addr(3 downto 0)="0001" then 
			dma_wr_addr_reg(23 downto 16) <= inmem_data(23 downto 16);
		end if;
		if inmem_we(3)='1' and  inmem_addr(14 downto 12) = "010" and inmem_addr(3 downto 0)="0001" then 
			dma_wr_addr_reg(31 downto 24) <= inmem_data(31 downto 24);
		end if;
		-- 010 xxxx xxxx 0010 - cor_space_in_reg
		if inmem_we(0)='1' and  inmem_addr(14 downto 12) = "010" and inmem_addr(3 downto 0)="0010" then 
			cor_space_in_reg(7 downto 0) <= inmem_data(7 downto 0);
		end if;
		if inmem_we(1)='1' and  inmem_addr(14 downto 12) = "010" and inmem_addr(3 downto 0)="0010" then 
			cor_space_in_reg(15 downto 8) <= inmem_data(15 downto 8);
		end if;
		if inmem_we(2)='1' and  inmem_addr(14 downto 12) = "010" and inmem_addr(3 downto 0)="0010" then 
			cor_space_in_reg(23 downto 16) <= inmem_data(23 downto 16);
		end if;
		if inmem_we(3)='1' and  inmem_addr(14 downto 12) = "010" and inmem_addr(3 downto 0)="0010" then 
			cor_space_in_reg(31 downto 24) <= inmem_data(31 downto 24);
		end if;			
		-- 010 xxxx xxxx 0011 - i2c_controlr
		if inmem_we(0)='1' and  inmem_addr(14 downto 12) = "010" and inmem_addr(3 downto 0)="0011" then 
			i2c_controlr(7 downto 0) <= inmem_data(7 downto 0);
		end if;
		if inmem_we(1)='1' and  inmem_addr(14 downto 12) = "010" and inmem_addr(3 downto 0)="0011" then 
			i2c_controlr(15 downto 8) <= inmem_data(15 downto 8);
		end if;
		if inmem_we(2)='1' and  inmem_addr(14 downto 12) = "010" and inmem_addr(3 downto 0)="0011" then 
			i2c_controlr(23 downto 16) <= inmem_data(23 downto 16);
		end if;
		if inmem_we(3)='1' and  inmem_addr(14 downto 12) = "010" and inmem_addr(3 downto 0)="0011" then 
			i2c_controlr(31 downto 24) <= inmem_data(31 downto 24);
		end if;
      -- 010 xxxx xxxx 0100 - 010 xxxx xxxx 1111 - reserve		
	end if;
end process;

i2c_control <= i2c_controlr;
dma_wr_addr <= dma_wr_addr_reg;
led_1 <= cor_ctrl(0);
led_2 <= cor_ctrl(1);
irq_enable <= cor_ctrl(31);

-- we for NCO control mem - 000 xxxx xx00 0000 - 000 xxxx xx11 1111 
nco_imem_we1 <= inmem_we when inmem_addr(14 downto 12)="000" and inmem_addr(5)='0' else "0000"; -- nco control mem1 
nco_imem_we2 <= inmem_we when inmem_addr(14 downto 12)="000" and inmem_addr(5)='1' else "0000"; -- nco control mem2
-- we for PRN mem
prn_mem_we1 <= inmem_we when inmem_addr(14 downto 12)="100" else "0000"; -- PRN mem for corr  1 - 6
prn_mem_we2 <= inmem_we when inmem_addr(14 downto 12)="101" else "0000"; -- PRN mem for corr  7 - 12
prn_mem_we3 <= inmem_we when inmem_addr(14 downto 12)="110" else "0000"; -- PRN mem for corr 13 - 18
prn_mem_we4 <= inmem_we when inmem_addr(14 downto 12)="111" else "0000"; -- PRN mem for corr 19 - 24

-- input memory for nco_phase and nco_code control
				  
-- nco_phase memory output decoding 					  
b_code1  <= nco_imem_out1(31 downto 0); 	-- b_code for corr   1 - 6
b_phase1 <= nco_imem_out1(63 downto 32);	-- b_phase for corr  1 - 6
b_code2  <= nco_imem_out1(95 downto 64);	-- b_code for corr   7 - 12
b_phase2 <= nco_imem_out1(127 downto 96);	-- b_phase for corr  7 - 12
b_code3  <= nco_imem_out2(31 downto 0);	-- b_code for corr  13 - 18
b_phase3 <= nco_imem_out2(63 downto 32);	-- b_phase for corr 13 - 18
b_code4  <= nco_imem_out2(95 downto 64);	-- b_code for corr  19 - 24
b_phase4 <= nco_imem_out2(127 downto 96); -- b_phase for corr 19 - 24

-- addr for nco_in_mem read (correlator)
nco_mem_addr(2 downto 0) <= phase_early;    -- 0~5, phase_pom in cor_timing.
nco_mem_addr(3) <= tic_page_early;          -- 

-- addr for nco_in_mem write (computer)
nco_imem_addr(4 downto 0) <= inmem_addr(4 downto 0);
nco_imem_addr(5) <= not tic_page;

-- port a - computer    width: 32 , depth: 64
-- port b - correlator  width: 128, depth: 16
nco_inm1 : nco_inmem
		port map (
			clka => clk_ctr,
			wea => nco_imem_we1,
			addra => nco_imem_addr,
			dina => inmem_data,
			clkb => clk_dsp,
			addrb => nco_mem_addr,
			doutb => nco_imem_out1);
			
nco_inm2 : nco_inmem
		port map (
			clka => clk_ctr,
			wea => nco_imem_we2,
			addra => nco_imem_addr,
			dina => inmem_data,
			clkb => clk_dsp,
			addrb => nco_mem_addr,
			doutb => nco_imem_out2);			

-- mems for correlators result  
cor_mem_in1(31 downto 0)   <= acc_e_out1;	-- early output from corr  1 - 6 
cor_mem_in1(63 downto 32)  <= acc_l_out1; -- late  output from corr  1 - 6
cor_mem_in1(95 downto 64)  <= acc_e_out2; -- early output from corr  7 - 12
cor_mem_in1(127 downto 96) <= acc_l_out2; -- late  output from corr  7 - 12

cor_mem_we1(0) <= prn_tic_e1;	-- early output from corr  1 - 6 we 
cor_mem_we1(1) <= prn_tic_e1;
cor_mem_we1(2) <= prn_tic_e1;
cor_mem_we1(3) <= prn_tic_e1;

cor_mem_we1(4) <= prn_tic_l1; -- late  output from corr  1 - 6 we
cor_mem_we1(5) <= prn_tic_l1;
cor_mem_we1(6) <= prn_tic_l1;
cor_mem_we1(7) <= prn_tic_l1;

cor_mem_we1(8) <= prn_tic_e2; -- early output from corr  7 - 12 we
cor_mem_we1(9) <= prn_tic_e2;
cor_mem_we1(10) <= prn_tic_e2;
cor_mem_we1(11) <= prn_tic_e2;

cor_mem_we1(12) <= prn_tic_l2; -- late  output from corr  7 - 12 we
cor_mem_we1(13) <= prn_tic_l2;
cor_mem_we1(14) <= prn_tic_l2;
cor_mem_we1(15) <= prn_tic_l2;

cor_mem_in2(31 downto 0)   <= acc_e_out3; -- early output from corr 13 - 18
cor_mem_in2(63 downto 32)  <= acc_l_out3; -- late  output from corr 13 - 18
cor_mem_in2(95 downto 64)  <= acc_e_out4; -- early output from corr 19 - 24
cor_mem_in2(127 downto 96) <= acc_l_out4; -- late  output from corr 19 - 24

cor_mem_we2(0) <= prn_tic_e3; -- early output from corr  13 - 18 we
cor_mem_we2(1) <= prn_tic_e3;
cor_mem_we2(2) <= prn_tic_e3;
cor_mem_we2(3) <= prn_tic_e3;

cor_mem_we2(4) <= prn_tic_l3; -- late  output from corr  13 - 18 we
cor_mem_we2(5) <= prn_tic_l3;
cor_mem_we2(6) <= prn_tic_l3;
cor_mem_we2(7) <= prn_tic_l3;

cor_mem_we2(8) <= prn_tic_e4; -- early output from corr  19 - 24 we
cor_mem_we2(9) <= prn_tic_e4;
cor_mem_we2(10) <= prn_tic_e4;
cor_mem_we2(11) <= prn_tic_e4;

cor_mem_we2(12) <= prn_tic_l4;-- late  output from corr  19 - 24 we
cor_mem_we2(13) <= prn_tic_l4;
cor_mem_we2(14) <= prn_tic_l4;
cor_mem_we2(15) <= prn_tic_l4;

-- addr for cor_out_mem read (computer)
cor_mem_addr_out(4 downto 0) <= outmem_addr(4 downto 0);
cor_mem_addr_out(5) <= not tic_page; 

-- addr for cor_mem_addr and nco_out_mem results write (correlator)
cor_mem_addr(2 downto 0) <= phase;
cor_mem_addr(3) <= tic_page;

-- port a - correlator
-- port b - computer
cor_mem1 : cor_outmem	-- corrlators 1 - 12 output mem
		port map (
			clka => clk_dsp,
			wea => cor_mem_we1,
			addra => cor_mem_addr,
			dina => cor_mem_in1,
			clkb => clk_ctr,
			enb => outmem_ce,
			addrb => cor_mem_addr_out,
			doutb => cor_mem_out1);
			
cor_mem2 : cor_outmem	-- corrlators 13 - 24 output mem
		port map (
			clka => clk_dsp,
			wea => cor_mem_we2,
			addra => cor_mem_addr,
			dina => cor_mem_in2,
			clkb => clk_ctr,
			enb => outmem_ce,
			addrb => cor_mem_addr_out,
			doutb => cor_mem_out2);	

-- signal snapshot output mem
-- port a - correlator width: 16 bit
-- port b - computer   width: 32 bit
	acq_m : acq_outmem
		port map (
			clka => clk_dsp,
			wea => acq_mem_we,
			addra => acq_mem_addr_in,
			dina => acq_mem_in,
			clkb => clk_ctr,
			enb => outmem_ce,
			addrb => acq_mem_addr_out, 
			doutb => acq_mem_out);

acq_mem_addr_out(13) <= not tic_page;
acq_mem_addr_out(12 downto 0) <= outmem_addr(12 downto 0);

-- output mem for code and phase measurement
nco_omem_in(31 downto 0)    <= codem_1;	-- nco code  output form cor  1 - 6
nco_omem_in(63 downto 32)   <= phasem_1;	-- nco phase output form cor  1 - 6
nco_omem_in(95 downto 64)   <= codem_2;	-- nco code  output form cor  7 - 12
nco_omem_in(127 downto 96)  <= phasem_2;	-- nco phase output form cor  7 - 12
nco_omem_in(159 downto 128) <= codem_3;	-- nco code  output form cor 13 - 18
nco_omem_in(191 downto 160) <= phasem_3;	-- nco phase output form cor 13 - 18
nco_omem_in(223 downto 192) <= codem_4;	-- nco code  output form cor 19 - 24
nco_omem_in(255 downto 224) <= phasem_4;	-- nco phase output form cor 19 - 24
nco_omem_we(0) <= tic; 

-- addr for read (computer)
nco_omem_addr(5 downto 0) <= outmem_addr(5 downto 0);
nco_omem_addr(6) <= not tic_page; 

-- port a - correlator
-- port b - computer	
nco_omem : nco_outmem
		port map (
			clka => clk_dsp,
			wea => nco_omem_we,
			addra => cor_mem_addr,
			dina => nco_omem_in,
			clkb => clk_ctr,
			enb => outmem_ce,
			addrb => nco_omem_addr,
			doutb => nco_omem_out);

-- addr signal delay for output multiplexer
process (clk_dsp)
begin
	if (clk_dsp'event and clk_dsp ='1') then
		if outmem_ce = '1' then
			outmem_addr_delay <= outmem_addr;
		end if;
	end if;
end process;

-- output mem multiplexer
-- Refer to "Witch Navigator FPGA Processor", 2.1 Output Memory Mapped Register, by zcz on 2015/8/16 17:57:08
-- acq_mem_out    	000 0000 0000 0000 - 
--                	111 1100 1111 1100 - 7CFCh
                             
-- nco_omem_out   	111 1101 0000 0000 - 7D00h
--                	111 1101 1111 1100 
                             
-- cor_mem_out1   	111 1110 0000 0000 - 7E00h
--                	111 1110 0111 1100
                             
-- cor_mem_out2   	111 1110 1000 0000 - 7E80h
--                	111 1110 1111 1100
 
-- cor_ctrl				111 1111 0000 0000 R/W  7F00h
-- cor_space_in_reg 	111 1111 0000 1000 R/W  7F08h
-- tin_no         	    111 1111 0001 0000      7F10
-- i2c_status       	111 1111 0001 1000      7F18h


-- by zcz: outmem_addr_delay is in units of DW (4Byte)
outmem_data <=  nco_omem_out 		when outmem_addr_delay(12 downto 6) = "1111101"     else    -- 7D00 ~ 7DFC
                cor_mem_out1 		when outmem_addr_delay(12 downto 5) = "11111100"    else    -- 7E00 ~ 7E7C
                cor_mem_out2 		when outmem_addr_delay(12 downto 5) = "11111101"    else    -- 7E80 ~ 7EFC
                cor_ctrl     		when outmem_addr_delay(12 downto 1) = "111111100000" else   -- 7F00 ~ 7F03
                cor_space_in_reg    when outmem_addr_delay(12 downto 1) = "111111100001" else   -- 7F08 ~ 7F0B
                tic_no       		when outmem_addr_delay(12 downto 1) = "111111100010" else   -- 7F10 ~ 7F13
                i2c_status   		when outmem_addr_delay(12 downto 1) = "111111100011" else   -- 7F18 ~ 7F1B
                acq_mem_out;

	cor_time: cor_timing 
	GENERIC MAP(
	   tic_length => tic_length
		)
	PORT MAP(
		clk_in => clk_in,
		s1_in => s1_in,
		s2_in => s2_in,
		clk_adc => clk_adc,
		clk_dsp => clk_dsp,
		tic => tic,
		dma_ctrl => dma_ctrl,
		phase => phase,
		tic_page => tic_page,
		phase_early => phase_early,
		tic_page_early => tic_page_early,
		sr1_out => sr1_out,
		si1_out => si1_out,
		sr2_out => sr2_out,
		si2_out => si2_out,
		agc1 => agc1,
		agc2 => agc2,
		acq_mem_addr => acq_mem_addr_in(13 downto 0),
		acq_mem_we => acq_mem_we(0),
		acq_mem_data => acq_mem_in,
		tic_no_counter => tic_no(15 downto 0),
		acq_ctr => cor_ctrl(11 downto 8)
	);

acq_mem_addr_in(14) <= tic_page;
tic_no(31 downto 16) <= "0000000000000000";		
		------------------------------------------------------------------------
		-- test outputs, comment after debuging
--		b_code_test <= b_code1;
--		b_phase_test <= b_phase1;
--		sr_in_test <= sr1_out;
--		si_in_test <= si1_out;
--		cor_space_test <= cor_space_in_reg(2 downto 0);
--		phase_test <= phase;
--		nco_code_out_test <= codem_1;
--		nco_phase_out_test <= phasem_1;
--		acc_e_out_test <= acc_e_out1;
--		acc_l_out_test <= acc_l_out1;
--		prn_tic_e_test <= prn_tic_e1;
--		prn_tic_l_test <= prn_tic_l1;
		-- end of test outputs
		------------------------------------------------------------------------
	
	-- cor 1 - 6	
	cor6_1: cor6 
	GENERIC MAP(
		prn_length => prn_length1_6		
	)
	PORT MAP(
		sr_in => sr1_out,
		si_in => si1_out,
		clk_dsp => clk_dsp,
		b_code => b_code1,
		b_phase => b_phase1,
		cor_space => cor_space_in_reg(2 downto 0),
		phase => phase,
		nco_code_out => codem_1,
		nco_phase_out => phasem_1,
		acc_e_out => acc_e_out1,
		acc_l_out => acc_l_out1,
		prn_tic_e => prn_tic_e1,
		prn_tic_l => prn_tic_l1,
		clk_ctr => clk_ctr,
		prn_mem_we => prn_mem_we1,
		prn_mem_addr => inmem_addr(11 downto 0),
		prn_mem_in => inmem_data
	);
	-- cor 7 - 12
	cor6_2: cor6 
	GENERIC MAP(
		prn_length => prn_length7_12		
	)
	PORT MAP(
		sr_in => sr1_out,
		si_in => si1_out,
		clk_dsp => clk_dsp,
		b_code => b_code2,
		b_phase => b_phase2,
		cor_space => cor_space_in_reg(6 downto 4),
		phase => phase,
		nco_code_out => codem_2,
		nco_phase_out => phasem_2,
		acc_e_out => acc_e_out2,
		acc_l_out => acc_l_out2,
		prn_tic_e => prn_tic_e2,
		prn_tic_l => prn_tic_l2,
		clk_ctr => clk_ctr,
		prn_mem_we => prn_mem_we2,
		prn_mem_addr => inmem_addr(11 downto 0),
		prn_mem_in => inmem_data
	);
	-- cor 13 - 18
	cor6_3: cor6
	GENERIC MAP(
		prn_length => prn_length13_18		
	)
	PORT MAP(
		sr_in => sr2_out,
		si_in => si2_out,
		clk_dsp => clk_dsp,
		b_code => b_code3,
		b_phase => b_phase3,
		cor_space => cor_space_in_reg(10 downto 8),
		phase => phase,
		nco_code_out => codem_3,
		nco_phase_out => phasem_3,
		acc_e_out => acc_e_out3,
		acc_l_out => acc_l_out3,
		prn_tic_e => prn_tic_e3,
		prn_tic_l => prn_tic_l3,
		clk_ctr => clk_ctr,
		prn_mem_we => prn_mem_we3,
		prn_mem_addr => inmem_addr(11 downto 0),
		prn_mem_in => inmem_data
	);	
	-- cor 19 - 24
	cor6_4: cor6
	GENERIC MAP(
		prn_length => prn_length19_24		
	)
	PORT MAP(
		sr_in => sr2_out,
		si_in => si2_out,
		clk_dsp => clk_dsp,
		b_code => b_code4,
		b_phase => b_phase4,
		cor_space => cor_space_in_reg(14 downto 12),
		phase => phase,
		nco_code_out => codem_4,
		nco_phase_out => phasem_4,
		acc_e_out => acc_e_out4,
		acc_l_out => acc_l_out4,
		prn_tic_e => prn_tic_e4,
		prn_tic_l => prn_tic_l4,
		clk_ctr => clk_ctr,
		prn_mem_we => prn_mem_we4,
		prn_mem_addr => inmem_addr(11 downto 0),
		prn_mem_in => inmem_data
	);	
end Behavioral;
